import * as Blockly from 'blockly/core';
import * as layui from 'layui';
import * as Mixly from 'mixly';
import * as ace from 'ace';
import $ from 'jquery';
import shortid from 'shortid';
import TEMPLATE from './template/block-tool-workspace.html';

const { element } = layui;
const {
    Config,
    LayerExt,
    XML
} = Mixly;
const { USER } = Config;

const BlockTool = {};

BlockTool.DEBUG = false;

BlockTool.WORKSPACE_CONTAINER = XML.render(TEMPLATE, {
    mId: shortid.generate()
});
BlockTool.BLOCK_TOOL_VIEW_TYPE = 'block_tool_view';
BlockTool.BLOCK_TOOL_VIEW_XML = '<block type="block_tool_view"></block>';
BlockTool.blockCode = '';
BlockTool.generatorCode = '';
BlockTool.xmlCode = '';
BlockTool.workspace = BlockTool.workspace ?? null;
BlockTool.layerNum = -1;
BlockTool.ace = BlockTool.ace ?? {};
BlockTool.viewerTabIndex = BlockTool.viewerTabIndex ?? null;
BlockTool.$content = $(BlockTool.WORKSPACE_CONTAINER);
BlockTool.$container = BlockTool.$content.children('div');
BlockTool.$workspaceContainer = BlockTool.$content.find('.workspace-container');
BlockTool.$blockContainer = BlockTool.$content.find('.block-container');
BlockTool.$generatorContainer = BlockTool.$content.find('.generator-container');
BlockTool.$xmlContainer = BlockTool.$content.find('.xml-container');
BlockTool.$blocksXmlContainer = BlockTool.$content.find('.blocks-xml-container');
BlockTool.$errorContainer = BlockTool.$content.find('.error-container');

BlockTool.createBlockToolWorkspace = () => {
    const media = Config.pathPrefix + 'common/media/blockly/';
    const renderer = ['geras', 'zelos'].includes(USER.blockRenderer) ? USER.blockRenderer : 'geras';
    const workspace = Blockly.inject(BlockTool.$workspaceContainer[0], {
        renderer,
        media,
        move: {
            scrollbars: {
                horizontal: true,
                vertical: true
            },
            drag: true,
            wheel: false
        },
        zoom: {
            controls: true,
            wheel: true,
            scaleSpeed: 1.03
        },
        readOnly: false
    });
    if (USER.theme === 'dark') {
        workspace.setTheme(Blockly.Themes.Dark);
    } else {
        workspace.setTheme(Blockly.Themes.Classic);
    }
    return workspace;
}

BlockTool.createBlockToolCodeEditor = (container, language = 'javascript', tabSize = 4) => {
    let codeEditor = ace.edit(container);
    if (USER.theme === 'dark') {
        codeEditor.setTheme('ace/theme/dracula');
    } else {
        codeEditor.setTheme('ace/theme/xcode');
    }
    codeEditor.getSession().setMode(`ace/mode/${language}`);
    codeEditor.getSession().setTabSize(tabSize);
    codeEditor.setFontSize(15);
    codeEditor.setShowPrintMargin(false);
    codeEditor.setReadOnly(true);
    codeEditor.setScrollSpeed(0.8);
    codeEditor.setOptions({
        enableBasicAutocompletion: true,
        enableSnippets: true,
        enableLiveAutocompletion: true
    });
    codeEditor.setValue('', -1);
    return codeEditor;
}

BlockTool.blockToolViewClickFunc = () => {
    if (BlockTool.layerNum !== -1) {
        return;
    }
    BlockTool.layerNum = LayerExt.open({
        title: ['图形块预览框', '35px'],
        id: 'block-tool-layer',
        content: BlockTool.$content,
        shade: 0,
        area: ['30%', '40%'],
        min: ['520px', '200px'],
        max: ['900px', '400px'],
        zIndex: 9000,
        success: (layero) => {
            layero.find('.injectionDiv').css('border-radius', layero.css('border-radius'));
            $(BlockTool.workspace.getParentSvg()).attr({
                width: BlockTool.$workspaceContainer.width(),
                height: BlockTool.$workspaceContainer.height()
            });
            element.tabChange('block-tool-viewer-filter', 'blockViewer');
            BlockTool.viewerTabIndex = 'blockViewer';
            Blockly.svgResize(BlockTool.workspace);
            if (!Blockly.Blocks.block_tool_view) {
                return;
            }
            BlockTool.workspace.clear();
            let $block = $('<xml>' + BlockTool.xmlCode + '</xml>');
            if ($block.length) {
                $block.children('block').attr('type', BlockTool.BLOCK_TOOL_VIEW_TYPE);
            } else {
                $block = $(`<xml>${BlockTool.BLOCK_TOOL_VIEW_XML}</xml>`);
            }
            try {
                Blockly.Xml.domToWorkspace($block[0], BlockTool.workspace);
            } catch (error) {
                BlockTool.$errorContainer.html(error.name + ' - ' + error.message);
                $block = $(`<xml>${BlockTool.BLOCK_TOOL_VIEW_XML}</xml>`);
                Blockly.Xml.domToWorkspace($block[0], BlockTool.workspace);
                if (BlockTool.DEBUG) {
                    console.log(error);
                }
            }
            BlockTool.workspace.scrollCenter();
        },
        resizing: () => {
            switch (BlockTool.viewerTabIndex) {
            case 'blockViewer':
                $(BlockTool.workspace.getParentSvg()).attr({
                    width: BlockTool.$workspaceContainer.width(),
                    height: BlockTool.$workspaceContainer.height()
                });
                Blockly.svgResize(BlockTool.workspace);
                break;
            case 'blockEditor':
                BlockTool.ace.block.resize();
                break;
            case 'generatorEditor':
                BlockTool.ace.generator.resize();
                break;
            case 'xmlEditor':
                BlockTool.ace.xml.resize();
                break;
            case 'blocksXmlEditor':
                BlockTool.ace.blocksXml.resize();
                BlockTool.viewerTabIndex = 'blocksXmlEditor';
                break;
            }
        },
        end: () => {
            BlockTool.layerNum = -1;
        }
    });
}

export default BlockTool;